package com.hanter.android.radwidget.recyclerview.decoration;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

public class GridItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable mDivider;
    private int mSpanCount; // 显示的列数
    private boolean mIncludeEdge;
    private int mWidth; // Divider Width
    private int mHeight; // Divider Height

    public GridItemDecoration(@NonNull Context context, int spanCount) {
        this(context, spanCount, android.R.color.transparent);
    }

    public GridItemDecoration(@NonNull Context context, int spanCount, @DrawableRes int color) {
        mDivider = ContextCompat.getDrawable(context, color);
        mSpanCount = spanCount;
    }

    @Override
    public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        drawHorizontal(c, parent);
        drawVertical(c, parent);
    }

    private int getSpanCount(RecyclerView parent) {
        // 列数
        int spanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {

            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager)
                    .getSpanCount();
        }
        return spanCount;
    }

    private void drawHorizontal(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getLeft() - params.leftMargin;
            final int right = child.getRight() + params.rightMargin
                    + getDividerWidth();
            int top;
            int bottom;

            if ((i / mSpanCount) == 0) {
                //画item最上面的分割线
                top = 0;
                bottom = top + getDividerHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
                //画item下面的分割线
                top = child.getBottom() + params.bottomMargin;
                bottom = top + getDividerHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            } else {
                //画item下面的分割线
                top = child.getBottom() + params.bottomMargin;
                bottom = top + getDividerHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }

        }
    }

    private void drawVertical(Canvas c, RecyclerView parent) {
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getTop() - params.topMargin;
            final int bottom = child.getBottom() + params.bottomMargin;
            int left;
            int right;

            if ((i % mSpanCount) == 0) {
                //item左边分割线
                left = 0;
                right = left + getDividerWidth();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
                //item右边分割线
                left = child.getRight() + params.rightMargin;
                right = left + getDividerWidth();
            } else {
                left = child.getRight() + params.rightMargin;
                right = left + getDividerWidth();
            }
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    private boolean isFirstColumn(RecyclerView parent, int pos, int spanCount,
                                  int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            return pos % spanCount == 0;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation();
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                return pos % spanCount == 0;
            } else {
                childCount = childCount - childCount % spanCount;
                return pos >= childCount;
            }
        }
        return false;
    }

    private boolean isLastColumn(RecyclerView parent, int pos, int spanCount,
                                 int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            return (pos + 1) % spanCount == 0;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                return (pos + 1) % spanCount == 0;
            } else {
                childCount = childCount - childCount % spanCount;
                return pos >= childCount;
            }
        }
        return false;
    }

    private boolean isLastRow(RecyclerView parent, int pos, int spanCount,
                              int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            childCount = childCount - childCount % spanCount;
            // 如果是最后一行，则不需要绘制底部
            return pos >= childCount;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            // StaggeredGridLayoutManager 且纵向滚动
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                childCount = childCount - childCount % spanCount;
                // 如果是最后一行，则不需要绘制底部
                return pos >= childCount;
            } else { // StaggeredGridLayoutManager 且横向滚动
                // 如果是最后一行，则不需要绘制底部
                return (pos + 1) % spanCount == 0;
            }
        }
        return false;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        RecyclerView.Adapter adapter = parent.getAdapter();
        if (adapter == null) {
            return;
        }

        int itemPosition = parent.getChildAdapterPosition(view);
        int spanCount = getSpanCount(parent);
        int childCount = adapter.getItemCount();

        int left, top, right, bottom;
        int column = itemPosition % spanCount;
        if (mIncludeEdge) {
            left = getDividerWidth() - column * getDividerWidth() / spanCount; // getDividerWidth() - column * ((1f / spanCount) * getDividerWidth())
            right = (column + 1) * getDividerWidth() / spanCount; // (column + 1) * ((1f / spanCount) * getDividerWidth())
        } else {
            left = column * getDividerWidth() / spanCount; // column * ((1f / spanCount) * getDividerWidth())
            right = getDividerWidth() - (column + 1) * getDividerWidth() / spanCount; // getDividerWidth() - (column + 1) * ((1f /    spanCount) * getDividerWidth())
        }

        top = 0;
        bottom = 0;
        if (mIncludeEdge) {
            if (itemPosition < spanCount) { // top edge
                top = getDividerHeight();
            }
            bottom = getDividerHeight(); // item bottom
        } else {
            if (itemPosition >= spanCount) {
                top = getDividerHeight(); // item top
            }
        }

        outRect.set(left, top, right, bottom);
    }

    public void setDividerWidth(int width) {
        this.mWidth = width;
    }

    public void setDividerHeight(int height) {
        this.mHeight = height;
    }

    public int getDividerWidth() {
        return mWidth > 0 ? mWidth : mDivider.getIntrinsicWidth();
    }

    public int getDividerHeight() {
        return mHeight > 0 ? mHeight : mDivider.getIntrinsicHeight();
    }

}